/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Dominio;

import java.util.LinkedList;

/**
 *
 * @author beatriz
 */
public class Nodo implements Comparable, Cloneable {

    private float funcionValoracion;
    private Nodo nodoPadre;
    private Estado estado;

    //Constructor para nodo inicial
    public Nodo(float funcionValoracion, Nodo nodoPadre, Estado estado) {
        this.funcionValoracion = funcionValoracion;
        this.nodoPadre = nodoPadre;
        this.estado = estado;
    }

    public float getCoste() {
        float coste;
        if (nodoPadre == null) {
            coste = estado.getCosto();
        } else {
            coste = nodoPadre.getCoste() + estado.getCosto();
        }
        return coste;
    }

    public float getFuncionValoracion() {
        return funcionValoracion;
    }

    public void setNodoPadre(Nodo nodoPadre) {
        this.nodoPadre = nodoPadre;
    }

    public int compareTo(Object nodo) {
        Nodo n = (Nodo) nodo;
        int resultado = -1;

        if (this.equals(nodo)) {
            resultado = 0;
        } else {
            if (n != null && this.getFuncionValoracion() < n.getFuncionValoracion()) {
                resultado = -1;
            }
            if (n != null && this.getFuncionValoracion() > n.getFuncionValoracion()) {
                resultado = 1;
            }
        }
        return resultado;
    }

    @Override
    public boolean equals(Object o) {
        Nodo n = (Nodo) o;
        if (this.getNodoPadre() == null && n.getNodoPadre() == null) {
            if (this.getEstado().getIdNodo() == n.getEstado().getIdNodo() && this.getEstado().getProfundidad() == n.getEstado().getProfundidad()) {
                return true;
            } else {
                return false;
            }
        } else {
            if (this.getNodoPadre() != null && n.getNodoPadre() != null) {
                if (this.getEstado().getIdNodo() == n.getEstado().getIdNodo() && this.getNodoPadre().equals(n.getNodoPadre()) && this.getEstado().getProfundidad() == n.getEstado().getProfundidad()) {
                    return true;
                } else {
                    return false;
                }

            } else {
                return false;
            }
        }
    }

    @Override
//    public String toString() {
//        return Float.toString(this.funcionValoracion);
//    }
    public String toString() {
        Nodo aux = this;
        float costeTotal = 0;
        LinkedList<Integer> list = new LinkedList<Integer>();
        while (aux.getNodoPadre() != null) {
            list.addFirst(aux.getEstado().getIdNodo());
            costeTotal += aux.getEstado().getCosto();
            aux = aux.getNodoPadre();
        }
        costeTotal += aux.getEstado().getCosto();
        list.addFirst(aux.getEstado().getIdNodo());
        return list.toString() + "\nCoste: " + this.getCoste() + "\nProfundidad: " + this.getEstado().getProfundidad();

    }

    public Estado getEstado() {
        return estado;
    }

    public Nodo getNodoPadre() {
        return nodoPadre;
    }

    @Override
    public Object clone() {
        Object copia = null;
        try {
            copia = super.clone();
        } catch (CloneNotSupportedException e) {
            System.out.println("Error al clonar el nodo");
        }
        ((Nodo) copia).setFuncionValoracion(funcionValoracion);
        if (nodoPadre != null) {
            ((Nodo) copia).setNodoPadre((Nodo) nodoPadre.clone());
        } else {
            ((Nodo) copia).setNodoPadre(null);
        }
        ((Nodo) copia).setEstado((Estado) estado.clone());
        return copia;
    }

    public void setEstado(Estado estado) {
        this.estado = estado;
    }

    public void setFuncionValoracion(float funcionValoracion) {
        this.funcionValoracion = funcionValoracion;
    }
}
